home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-13 / mewin10s.zip / SCREEN.C < prev    next >
C/C++ Source or Header  |  1992-03-15  |  11KB  |  462 lines

  1. /*    SCREEN.C:    Screen manipulation commands
  2.             for MicroEMACS 3.11
  3.             written by Daniel Lawrence
  4. */
  5.  
  6. #include    <stdio.h>
  7. #include    "estruct.h"
  8. #include    "eproto.h"
  9. #include        "edef.h"
  10. #include    "elang.h"
  11.  
  12. #if    0
  13. dumpscreens(msg)
  14.  
  15. char *msg;
  16.  
  17. {
  18.     SCREEN *sp;
  19.  
  20.     printf("<%s>\n", msg);
  21.     sp = first_screen;
  22.     while (sp != (SCREEN *)NULL) {
  23.         printf("%lu - [%s] %d/%d to %d/%d \n", sp, sp->s_screen_name,
  24.         sp->s_roworg, sp->s_colorg, sp->s_nrow, sp->s_ncol);
  25.         sp = sp->s_next_screen;
  26.     }
  27.     printf("   0     -   [EOL]\n");
  28.     tgetc();
  29. }
  30. #endif
  31.  
  32. /*    This command takes the last window in the linked window list,
  33.     which is visibly rearmost, and brings it to front. It is bound
  34.     to A-N on machines with an ALT key
  35. */
  36.  
  37. PASCAL NEAR cycle_screens(f, n)
  38.  
  39. int f,n;    /* prefix flag and argument */
  40.  
  41. {
  42.     SCREEN *sp;        /* ptr to screen to switch to */
  43.  
  44.     /* find the last screen */
  45.     sp = first_screen;
  46.     while (sp->s_next_screen != (SCREEN *)NULL)
  47.         sp = sp->s_next_screen;
  48.  
  49.     /* and make this screen current */
  50.     return(select_screen(sp, TRUE));
  51. }
  52.  
  53. PASCAL NEAR find_screen(f, n)
  54.  
  55. int f,n;    /* prefix flag and argument */
  56.  
  57. {
  58.     char scr_name[NSTRING];    /* buffer to hold screen name */
  59.     SCREEN *sp;        /* ptr to screen to switch to */
  60.     int     result;
  61.  
  62.     /* get the name of the screen to switch to */
  63.     if ((result = mlreply(TEXT242, scr_name, NSTRING)) != TRUE) {
  64.         /* "Find Screen: " */
  65.             return result;
  66.     } 
  67.     sp = lookup_screen(scr_name);
  68.  
  69.     if (sp == (SCREEN *)NULL) {
  70.  
  71.         /* save the current dot position in the buffer info
  72.            so the new screen will start there! */
  73.         curbp->b_dotp = curwp->w_dotp;
  74.         curbp->b_doto = curwp->w_doto;
  75.  
  76.         /* screen does not exist, create it */
  77.         sp = init_screen(scr_name, curbp);
  78.     }
  79.  
  80.     /* and make this screen current */
  81.     return(select_screen(sp, TRUE));
  82. }
  83.  
  84. PASCAL NEAR free_screen(sp)    /* free all resouces associated with a screen */
  85.  
  86. SCREEN *sp;    /* screen to dump */
  87.  
  88. {
  89.     register int cmark;    /* mark ordinal index */
  90.     register WINDOW *wp;    /* ptr to window to free */
  91.     register WINDOW *tp;    /* temp window pointer */
  92.  
  93.     /* first, free the screen's windows */
  94.     wp = sp->s_first_window;
  95.     while (wp) {
  96.         if (--wp->w_bufp->b_nwnd == 0) {
  97.             wp->w_bufp->b_dotp  = wp->w_dotp;
  98.             wp->w_bufp->b_doto  = wp->w_doto;
  99.             for (cmark = 0; cmark < NMARKS; cmark++) {
  100.                 wp->w_bufp->b_markp[cmark] = wp->w_markp[cmark];
  101.                 wp->w_bufp->b_marko[cmark] = wp->w_marko[cmark];
  102.             }
  103.             wp->w_bufp->b_fcol  = wp->w_fcol;
  104.         }
  105.  
  106.         /* on to the next window, free this one */
  107.         tp = wp->w_wndp;
  108.         free((char *) wp);
  109.         wp = tp;
  110.     }
  111.  
  112. #if     WINDOW_MSWIN
  113.         term.t_delscr(sp);
  114. #endif
  115.  
  116.     /* and now, free the screen struct itself */
  117.     free(sp->s_screen_name);
  118.     free((char *) sp);
  119. }
  120.  
  121. PASCAL NEAR unlist_screen(sp)
  122.  
  123. SCREEN *sp;         /* screen to remove from the list */
  124. {
  125.     SCREEN *last_scr;    /* screen previous to one to delete */
  126.  
  127.     last_scr = first_screen;
  128.     while (last_scr) {
  129.         if (last_scr->s_next_screen == sp)
  130.             break;
  131.         last_scr = last_scr->s_next_screen;
  132.     }
  133.     last_scr->s_next_screen = sp->s_next_screen;
  134. }
  135.  
  136. PASCAL NEAR delete_screen(f, n)
  137.  
  138. int f,n;    /* prefix flag and argument */
  139.  
  140. {
  141.     char scr_name[NSTRING];    /* buffer to hold screen name */
  142.     SCREEN *sp;        /* ptr to screen to switch to */
  143.     int     result;
  144.  
  145.     /* get the name of the screen to delete */
  146.     if ((result = mlreply(TEXT243, scr_name, NSTRING)) != TRUE) {
  147.         /* "Delete Screen: " */
  148.             return result;
  149.     } 
  150.     sp = lookup_screen(scr_name);
  151.  
  152.     /* make sure it exists... */
  153.     if (sp == (SCREEN *)NULL) {
  154.         mlwrite(TEXT240);   /* "[No such screen]" */
  155.         return(FALSE);
  156.     }
  157.  
  158.     /* it can't be current... */
  159.     if (sp == first_screen) {
  160.         mlwrite(TEXT241);   /* "%%Can't delete current screen" */
  161.         return(FALSE);
  162.     }
  163.  
  164.     unlist_screen(sp);
  165.     free_screen(sp);
  166. #if    WINDOW_TEXT
  167.             refresh_screen(first_screen);
  168. #endif
  169.     return(TRUE);
  170. }
  171.  
  172. /* this function initializes a new screen.... */
  173.  
  174. SCREEN *PASCAL NEAR init_screen(scr_name, scr_buf)
  175.  
  176. char *scr_name;        /* screen name */
  177. BUFFER *scr_buf;    /* buffer to place in first window of screen */
  178.  
  179. {
  180.     int cmark;        /* current mark to initialize */
  181.     SCREEN *sp;        /* pointer to allocated screen */
  182.     SCREEN *last_sp;    /* pointer to last screen */
  183.     WINDOW *wp;        /* ptr to first window of new screen */
  184.  
  185.     /* allocate memory for this screen */
  186.     sp = (SCREEN *)malloc(sizeof(SCREEN));
  187.     if (sp == (SCREEN *)NULL)
  188.         return(sp);
  189.  
  190.     /* set up this new screens fields! */
  191.     sp->s_next_screen = (SCREEN *)NULL;
  192.     sp->s_screen_name = copystr(scr_name);
  193. #if     WINDOW_MSWIN
  194.     if (term.t_newscr (sp) != TRUE) {       /* failed */
  195.         free ((void *)sp);
  196.         return ((SCREEN *)NULL);
  197.     }
  198.     /* ... in MSWIN, the s_nrow/ncol etc... values are kept up to
  199.        date by vtinitscr; besides, term entries may actually match
  200.        the first_screen instead of the new screen */
  201.     term.t_roworg = sp->s_roworg;
  202.     term.t_colorg = sp->s_colorg;
  203.     term.t_nrow = sp->s_nrow;
  204.     term.t_ncol = sp->s_ncol;
  205. #else
  206.     sp->s_roworg = term.t_roworg;
  207.     sp->s_colorg = term.t_colorg;
  208.     sp->s_nrow = term.t_nrow;
  209.     sp->s_ncol = term.t_ncol;
  210. #endif
  211.     /* allocate its first window */
  212.     wp = (WINDOW *)malloc(sizeof(WINDOW));
  213.     if (wp == (WINDOW *)NULL) {
  214.         free((char *)sp);
  215.         return((SCREEN *)NULL);
  216.     }
  217.     sp->s_first_window = sp->s_cur_window = wp;
  218.  
  219.     /* and setup the windows info */
  220.     wp->w_wndp = NULL;
  221.     wp->w_bufp = scr_buf;
  222.     scr_buf->b_nwnd += 1;    
  223.     wp->w_linep = scr_buf->b_linep;
  224.  
  225.     /* position us at the buffers dot */
  226.     wp->w_dotp  = scr_buf->b_dotp;
  227.     wp->w_doto  = scr_buf->b_doto;
  228.  
  229.     /* set all the marks to UNSET */
  230.     for (cmark = 0; cmark < NMARKS; cmark++) {
  231.         wp->w_markp[cmark] = NULL;
  232.         wp->w_marko[cmark] = 0;
  233.     }
  234.     wp->w_toprow = 0;
  235. #if    COLOR
  236.     /* initalize colors to global defaults */
  237.     wp->w_fcolor = gfcolor;
  238.     wp->w_bcolor = gbcolor;
  239. #endif
  240.     wp->w_fcol = 0;
  241. #if WINDOW_MSWIN
  242.     wp->w_ntrows = sp->s_nrow-1;
  243. #else
  244.     wp->w_ntrows = term.t_nrow-1;        /* "-1" for mode line.    */
  245. #endif
  246.     wp->w_force = 0;
  247.     wp->w_flag  = WFMODE|WFHARD;        /* Full.        */
  248.  
  249.     /* first screen? */
  250.     if (first_screen == (SCREEN *)NULL) {
  251.         first_screen = sp;
  252.         return(sp);
  253.     }
  254.  
  255.     /* insert it at the tail of the screen list */
  256.     last_sp = first_screen;
  257.     while (last_sp->s_next_screen != (SCREEN *)NULL)
  258.         last_sp = last_sp->s_next_screen;
  259.     last_sp->s_next_screen = sp;
  260.  
  261.     /* and return the new screen pointer */
  262.     return(sp);
  263. }
  264.  
  265. SCREEN *PASCAL NEAR lookup_screen(scr_name)
  266.  
  267. char *scr_name;        /* named screen to find */
  268.  
  269. {
  270.     SCREEN *result;
  271.  
  272.     /* scan the screen list */
  273.     result = first_screen;
  274.     while (result) {
  275.  
  276.         /* if this is it, return its handle! */
  277.         if (strcmp(scr_name, result->s_screen_name) == 0)
  278.             return(result);
  279.  
  280.         /* on to the next screen */
  281.         result = result->s_next_screen;
  282.     }
  283.  
  284.     /* we didn't find it..... */
  285.     return((SCREEN *)NULL);
  286. }
  287.  
  288. int PASCAL NEAR select_screen(sp, announce)
  289.  
  290. SCREEN *sp;    /* ptr to screen to switch to */
  291. int announce;    /* announce the selection? */
  292.  
  293. {
  294.     WINDOW *temp_wp;    /* backup of current window ptr (curwp) */
  295.     SCREEN *temp_screen;    /* temp ptr into screen list */
  296.  
  297.     /* make sure there is something here to set to! */
  298.     if (sp == (SCREEN *)NULL)
  299.         return(FALSE);
  300.  
  301.     /* nothing to do, it is already current */
  302.     if (sp == first_screen)
  303.         return(TRUE);
  304.  
  305.     /* deselect the current window */
  306. #if     WINDOW_MSWIN
  307.         curwp->w_flag |= WFMODE;
  308. #else
  309.     temp_wp = curwp;
  310.     curwp = (WINDOW *)NULL;
  311.     modeline(temp_wp);
  312.     updupd(TRUE);
  313.     curwp = temp_wp;
  314. #endif
  315.  
  316.     /* save the current screens concept of current window */
  317.     first_screen->s_cur_window = curwp;
  318. #if     WINDOW_MSWIN
  319.         /* in MSWIN, the term entries may (but not always) already
  320.        reflect the new screen's size and the s_n... stuff is always
  321.        kept up to date by vtinitscr */
  322.     vtscreen (sp);
  323. #else
  324.     first_screen->s_roworg = term.t_roworg;
  325.     first_screen->s_colorg = term.t_colorg;
  326.     first_screen->s_nrow = term.t_nrow;
  327.     first_screen->s_ncol = term.t_ncol;
  328. #endif
  329.  
  330.     /* re-order the screen list */
  331.     temp_screen = first_screen;
  332.     while (temp_screen->s_next_screen != (SCREEN *)NULL) {
  333.         if (temp_screen->s_next_screen == sp) {
  334.             temp_screen->s_next_screen = sp->s_next_screen;
  335.             break;
  336.         }
  337.         temp_screen = temp_screen->s_next_screen;
  338.     }
  339.     sp->s_next_screen = first_screen;
  340.     first_screen = sp;
  341.  
  342.     /* reset the current screen, window and buffer */
  343.     wheadp = first_screen->s_first_window;
  344.     curwp = first_screen->s_cur_window;
  345.     curbp = curwp->w_bufp;
  346.  
  347.     /* let the display driver know we need a full screen update */
  348. #if     WINDOW_MSWIN
  349.         term.t_topscr (first_screen);
  350.         curwp->w_flag |= WFMODE;
  351.         update (FALSE);
  352. #else
  353.     update_size();
  354.     upwind();
  355. #endif
  356.     if (announce) {
  357.         mlwrite(TEXT225, first_screen->s_screen_name);
  358. /*            "[Switched to screen %s]" */
  359.     }
  360.     return(TRUE);
  361. }
  362.  
  363. /*    Build and popup a buffer containing the list of all screens.
  364.     Bound to "A-B".
  365. */
  366.  
  367. PASCAL NEAR list_screens(f, n)
  368.  
  369. int f,n;    /* prefix flag and argument */
  370.  
  371. {
  372.     register int status;    /* stutus return */
  373.  
  374.     if ((status = screenlist(f)) != TRUE)
  375.         return(status);
  376.     return(wpopup(slistp));
  377. }
  378.  
  379.  
  380. /*
  381.  * This routine rebuilds the
  382.  * text in the special secret buffer
  383.  * that holds the screen list. It is called
  384.  * by the list screens command. Return TRUE
  385.  * if everything works. Return FALSE if there
  386.  * is an error (if there is no memory). Iflag
  387.  * indecates weather to list hidden screens.
  388.  */
  389. PASCAL NEAR screenlist(iflag)
  390.  
  391. int iflag;    /* list hidden screen flag */
  392.  
  393. {
  394.     SCREEN *sp;        /* ptr to current screen to list */
  395.     WINDOW *wp;        /* ptr into current screens window list */
  396.     int status;        /* return status from functions */
  397.     char line[NSTRING];    /* buffer to construct list lines */
  398.     char bname[NSTRING];    /* name of next buffer */
  399.  
  400.     /* mark this buffer as unchanged so... */
  401.     slistp->b_flag &= ~BFCHG;
  402.  
  403.     /* we can dump it's old contents without complaint */
  404.     if ((status = bclear(slistp)) != TRUE)
  405.         return(status);
  406.  
  407.     /* there is no file connected with this buffer */
  408.     strcpy(slistp->b_fname, "");
  409.  
  410.     /* construct the header of this list */
  411.     if (addline(slistp, "Screen         Buffers") == FALSE
  412.      || addline(slistp, "------         -------") == FALSE)
  413.         return(FALSE);
  414.  
  415.     /* starting from the first screen */
  416.     sp = first_screen;
  417.  
  418.     /* scan all the screens */
  419.     while (sp) {
  420.  
  421.         /* construct the screen name */
  422.         strcpy(line, sp->s_screen_name);
  423.         strcat(line, "                ");
  424.         line[15] = 0;
  425.  
  426.         /* list this screens windows's buffer names */
  427.         wp = sp->s_first_window;
  428.         while (wp) {
  429.  
  430.             /* grab this window's buffer name */
  431.             strcpy(bname, wp->w_bufp->b_bname);
  432.  
  433.             /* handle full lines */
  434.             if (strlen(line) + strlen(bname) + 1 > 78) {
  435.                 if (addline(slistp, line) == FALSE)
  436.                     return(FALSE);
  437.                 strcpy(line, "               ");
  438.             }
  439.  
  440.             /* append this buffer name */
  441.             if (strlen(line) > 15)
  442.                 strcat(line, " ");
  443.             strcat(line, bname);
  444.  
  445.             /* on to the next window */
  446.             wp = wp->w_wndp;
  447.         }
  448.  
  449.         /* and add the line to the buffer */
  450.         if (addline(slistp, line) == FALSE)
  451.             return(FALSE);
  452.  
  453.         /* on to the next screen */
  454.         sp = sp->s_next_screen;
  455.     }
  456.  
  457.     /* all constructed! */
  458.     return(TRUE);
  459. }
  460.  
  461.  
  462.